#include <functional>
#include <iostream>

// 使用该函数模板接收其他的可调用对象
template<class F, class T>
T useF(F f, T x) {
    // 静态变量，同时打印静态变量的地址和值
    static int count = 0;
    std::cout << "count:" << ++count << std::endl;
    std::cout << "count:" << &count << std::endl;
    return f(x);
}

double f(double i) {
    return i / 2;
}

struct Functor {
    double operator()(double d)
    {
    return d / 3;
    }
};

// int main() {
//     // 函数名
//     std::cout << useF(f, 11.11) << std::endl;
//     std::cout << "\n";
//     // 函数对象
//     std::cout << useF(Functor(), 11.11) << std::endl;
//     std::cout << "\n";
    
//     // lamber表达式
//     std::cout << useF([](double d)->double{ return d/4; }, 11.11) << std::endl;
//     std::cout << "\n";
    
//     return 0;
// }

// int main() {
//     std::function<double(double)> func1 = f;
//     std::cout << useF(func1, 11.11) << std::endl;
//     std::cout << "\n";
//     // 函数对象
//     std::function<double(double)> func2 = Functor();
//     std::cout << useF(func2, 11.11) << std::endl;
//     std::cout << "\n";
//     // lamber表达式
//     std::function<double(double)> func3 = [](double d)->double{ return d / 4; };
//     std::cout << useF(func3, 11.11) << std::endl;
//     std::cout << "\n";
//     return 0;
// }

class Plus {
public:
    static int plusi(int x, int y) {
        return x + y;
    }

    double plusd(double x, double y) {
        return x + y;
    }
};

// int main() {
//     std::function<int(int, int)> addi = &Plus::plusi;

//     std::function<double(Plus*, double, double)> addd1 = &Plus::plusd;

//     std::function<double(Plus, double, double)> addd2 = &Plus::plusd;

//     std::cout << addi(1, 2) << std::endl;
//     Plus plus;
//     std::cout << addd1(&plus, 1.1, 2.2) << std::endl;
//     std::cout << addd2(Plus(), 1.1, 2.2) << std::endl;

//     return 0;
// }



// int Sub(int x, int y) {
//     return x - y;
// }

// int main() {
//     auto f1 = Sub;
//     std::cout << f1(10, 5) << std::endl;

//     auto f2 = std::bind(Sub, std::placeholders::_2, std::placeholders::_1);
//     std::cout << f2(10, 5) << std::endl;

//     return 0;
// }


// class Sub {
// public:
//     int sub(int x, int y) {
//         return x - y;
//     }
// };

// void Print(const std::string& param, int x, int y) {
//     std::cout << param << " " << x << " " << y << std::endl;
// }

// int main() {
//     auto f1 = std::bind(Print, "hello", std::placeholders::_1, std::placeholders::_2);
//     auto f2 = std::bind(Print, std::placeholders::_1, 6, std::placeholders::_2);
//     auto f3 = std::bind(Print, std::placeholders::_1, std::placeholders::_2, 7);

//     f1(5, 7);
//     f2("world", 10);
//     f2("world", 10);
//     return 0;
// }

// int main() {


//     // 不减少参数数量
//     auto f1 = std::bind(&Sub::sub, std::placeholders::_1, 
//         std::placeholders::_2, std::placeholders::_3);
//     // 减少参数数量
//     auto f2 = std::bind(&Sub::sub, Sub(), std::placeholders::_1, std::placeholders::_2);
//     Sub s;
//     auto f3 = std::bind(&Sub::sub, &s, std::placeholders::_1, std::placeholders::_2);

//     std::cout << f1(Sub(), 10, 5) << std::endl;    
//     std::cout << f2(10, 5) << std::endl;    
//     std::cout << f3(10, 5) << std::endl;    
//     return 0;
// }

double add(double x, double y) {
    return x + y;
}

int main() {
    auto f1 = std::bind<int>(add, std::placeholders::_1, std::placeholders::_2);
    std::cout << f1(3.3, 2.8) << std::endl;


    // function包装器也可以接收bind包装器的对象
    std::function<int(double, double)> f2 = f1;
    std::cout << f1(3.3, 2.8) << std::endl;
    
    return 0;
}